// Copyright (c) 2005  INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of cgal-python; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; version 2.1 of the License.
// See the file LICENSE.LGPL distributed with cgal-python.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $Id: Py_Sphere_3.cpp 167 2007-11-02 15:36:54Z spion $
// $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal-python/trunk/cgal-python/bindings/Kernel/Py_Sphere_3.cpp $
//
// Author(s)     : Naceur Meskini
//=========================================================================

#include <CGAL/basic.h>
#include <include/Kernels.h>

#include <boost/python.hpp>
#include <boost/cstdint.hpp>

const char* Sphere_3_doc[]={
"An object of type Sphere_3 is a sphere in the three-dimensional Euclidean space.\nThe sphere is oriented, i.e. its boundary has clockwise or counterclockwise orientation. \nThe boundary splits  E3 into a positive and a negative side, where the positive side is to the left of the boundary. \nThe boundary also splits  E3 into a bounded and an unbounded side. \nNote that the sphere can be degenerated, i.e. the squared radius may be zero.\n\
For more details see a C++ doc:\n\
http://www.cgal.org/Manual/3.2/doc_html/cgal_manual/Kernel_23_ref/Class_Sphere_3.html",
"\
c = Sphere_3( Point_3 center,squared_radius,Orientation ori = COUNTERCLOCKWISE)\
introduces a variable c of type Sphere_3. \nIt is initialized to the sphere with center center, squared radius squared_radius and orientation ori.\n\
Precondition: ori # COPLANAR,, and further, squared_radius >= 0.\n\n\
c = Sphere_3( Point_3 p,Point_3 q,Point_3 r,Point_3 s);\n\
introduces a variable c of type Sphere_3. \nIt is initialized to the unique sphere which passes through the points p, q,r and s. \nThe orientation of the sphere is the orientation of the point quadruple p, q, r,s.\n\
Precondition: p, q, r and s are not collinear.\n\n\
c = Sphere_3( Point_3 p,Point_3 q,Point_3 r, Orientation ori = COUNTERCLOCKWISE)\n\n\
introduces a variable c of type Sphere_3. It is initialized to the smallest sphere which passes through the points p,q and r.\n\
Precondition: ori # COPLANAR.\n\
c = Sphere_3( Point_3 p,Point_3 q,Orientation ori = COUNTERCLOCKWISE)\n\
introduces a variable c of type Sphere_3. \nIt is initialized to the smallest sphere which passes through p and q\n\
Precondition: ori # COPLANAR.\n\n\
c = Sphere_3( Point_3 center,Orientation ori = COUNTERCLOCKWISE)\n\
introduces a variable c of type Sphere_3. \nIt is initialized to the sphere with center center, squared radius zero and orientation ori.\n\
Precondition: ori # COPLANAR.\n\
Postcondition: c.is_degenerate() = true.",

"c.center(self) ->Point_3\nreturns the center of c.",

"c.squared_radius(self) ->double\nreturns the squared radius of c.",

"c.orientation(self) -> Orientation\nreturns the orientation of c.",

"c.bounded_side(self, Point_3 p) -> Bounded_side\nreturns ON_BOUNDED_SIDE, ON_BOUNDARY, \n\
or ON_UNBOUNDED_SIDE  iff p lies properly inside, on the boundary, or properly outside of c, resp.",

"c.oriented_side(self ,Point_3 p) ->Oriented_side\nreturns either the constant ON_ORIENTED_BOUNDARY, ON_POSITIVE_SIDE, \n\
or ON_NEGATIVE_SIDE, iff p lies on the boundary, properly on \n\
the positive side, or properly on the negative side of c, resp.",

"c.has_on_boundary(self , Point_3 p) -> bool",

"c.has_on_bounded_side(self , Point_3 p) -> bool",

"c.has_on_unbounded_side(self , Point_3 p) -> bool",

"c.has_on_negative_side(self , Point_3 p) -> bool",

"c.has_on_positive_side(self , Point_3 p) -> bool",

"c.is_degenerate(self) -> bool\nreturns true, iff c is degenerate, i.e. if c has squared radius zero.",

"c.opposite(self) -> Sphere_3\nreturns the sphere with the same center and squared radius as c but with opposite orientation .",

"c.bbox(self) -> Bbox_3\nreturns a bounding box containing c."
};

template<class Sphere_3>
boost::python::str py_repr_Sphere_3(const Sphere_3& s )
{
	using namespace boost::python;
	return str("Sphere_3("+ str(s.center()) +","+ str(s.squared_radius())+","+ str(s.orientation()) +")" );
}

template <class kernel > 
void Py_Sphere_3()
{
	typedef typename kernel::Point_3 							Point_3;
 	typedef typename kernel::Sphere_3 							Sphere_3;
 	typedef typename kernel::FT 								FT;

	using namespace boost::python;

        class_< Sphere_3 >("Sphere_3", Sphere_3_doc[0], init<>())
	.def(init< const Sphere_3& >(Sphere_3_doc[1]))
	.def(init< const Point_3&, const FT&, optional< const CGAL::Orientation& > >())
	.def(init< const Point_3&, const double&, optional< const CGAL::Orientation& > >())
	.def(init< const Point_3&, const Point_3&, const Point_3&, const Point_3& >())
	.def(init< const Point_3&, const Point_3&, const Point_3&, optional< const CGAL::Orientation& > >())
	.def(init< const Point_3&, const Point_3&, optional< const CGAL::Orientation& > >())
	.def(init< const Point_3&, optional< const CGAL::Orientation& > >())
	.def("center", &Sphere_3::center, BEF_33(by_cref, by_copy)(), Sphere_3_doc[2])
	.def("squared_radius", &Sphere_3::squared_radius, BEF_33(by_cref, by_copy)(), Sphere_3_doc[3])
	.def("orientation", &Sphere_3::orientation, Sphere_3_doc[4])
	.def("bounded_side", &Sphere_3::bounded_side, Sphere_3_doc[5])
	.def("oriented_side", &Sphere_3::oriented_side, Sphere_3_doc[6])
	.def("has_on_boundary", &Sphere_3::has_on_boundary, Sphere_3_doc[7])
	.def("has_on_bounded_side", &Sphere_3::has_on_bounded_side, Sphere_3_doc[8])
	.def("has_on_unbounded_side", &Sphere_3::has_on_unbounded_side, Sphere_3_doc[9])
	.def("has_on_negative_side", &Sphere_3::has_on_negative_side, Sphere_3_doc[10])
	.def("has_on_positive_side", &Sphere_3::has_on_positive_side, Sphere_3_doc[11])
	.def("is_degenerate", &Sphere_3::is_degenerate, Sphere_3_doc[12])
	.def("opposite", &Sphere_3::opposite, Sphere_3_doc[13])
	.def("bbox", &Sphere_3::bbox, Sphere_3_doc[14])
	.def("__repr__", &py_repr_Sphere_3<Sphere_3>)
	
//        .def("orthogonal_transform", &Sphere_3::orthogonal_transform)
        .def( self == self )
        .def( self != self )
	;
}


void export_Sphere_3()
{
	Py_Sphere_3<K>();
}
